﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading;

using ABCat.Core.Plugins.DataProviders;
using ABCat.Core.Plugins.DataSets;
using ABCat.Shared.Properties;

namespace ABCat.Core.Plugins.Catalog.GrouppingLogics
{
	/// <summary>
	/// Группа записей каталога
	/// </summary>
	public class Group : INotifyPropertyChanged
	{
		#region + Events +

		public event PropertyChangedEventHandler PropertyChanged;

		#endregion
		#region + Fields +

		public readonly HashSet<string> LinkedRecords = new HashSet<string>();

		/// <summary>Логика группировки, создавшая группу</summary>
		public readonly GrouppingLogicPluginBase OwnerLogic;

		private readonly List<Group> _children;

		private bool _isExpanded;
		private bool _isSelected;

		#endregion
		#region + Properties +

		/// <summary>
		/// Название группы
		/// </summary>
		public string Caption		{get; set;}
		/// <summary>
		/// Список непосредственных потомков группы
		/// </summary>
		public List<Group> Children
		{
			get { return _children; }
		}

		public bool IsExpanded
		{
			get { return _isExpanded; }
			set
			{
				if (value != _isExpanded)
				{
					_isExpanded = value;
					OnPropertyChanged();
				}

				// Expand all the way up to the root.
				if (_isExpanded && Parent != null)
					Parent.IsExpanded = true;
			}
		}

		public bool IsSelected
		{
			get { return _isSelected; }
			set
			{
				if (value != _isSelected)
				{
					_isSelected = value;
					OnPropertyChanged();
				}
			}
		}

		/// <summary>
		/// Уровень иерархии в дереве
		/// </summary>
		public int Level		{get; set;}
		public string LinkedObjectString		{get; set;}
		/// <summary>
		/// Родительская группа
		/// </summary>
		public Group Parent		{get; set;}

		#endregion
		#region + Ctor +

		/// <summary>
		/// Группа записей каталога
		/// </summary>
		/// <param name="ownerLogic">Логика группировки, создавшая группу</param>
		public Group(GrouppingLogicPluginBase ownerLogic)
		{
			OwnerLogic = ownerLogic;
			_children = new List<Group>();
		}

		#endregion
		#region + Logic +

		/// <summary>
		/// Начать асинхронное получение записей
		/// </summary>
		/// <param name="dbContainer">Контейнер БД</param>
		/// <param name="completedCallback">Метод завершения операции</param>
		/// <param name="cancellationToken">Токен отмены операции</param>
		public void BeginGetRecordsAsync(IDbContainer dbContainer, Action<IEnumerable<IAudioBook>, Exception> completedCallback, CancellationToken cancellationToken)
		{
			OwnerLogic.BeginGetRecordsAsync(dbContainer, this, completedCallback, cancellationToken);
		}

		[NotifyPropertyChangedInvocator]
		protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
		{
			PropertyChangedEventHandler handler = PropertyChanged;
			if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
		}

		#endregion
	}
}